package cn.edu.xjtu.android.emoji_warfare_android.engine;

import android.os.SystemClock;
import cn.edu.xjtu.android.emoji_warfare_android.engine.entity.Entity;
import cn.edu.xjtu.android.emoji_warfare_android.engine.shape.Rectangle;
import cn.edu.xjtu.android.emoji_warfare_android.engine.worker.CollideWorker;
import cn.edu.xjtu.android.emoji_warfare_android.engine.worker.DelayedWorker;
import cn.edu.xjtu.android.emoji_warfare_android.engine.worker.MoveWorker;
import cn.edu.xjtu.android.emoji_warfare_android.engine.worker.RenderWorker;

/**
 * 基础引擎<br>
 * 包括必要的多个Worker
 * 
 * @author bill
 *
 */
public abstract class BaseEngine {
    /**
     * 动态实体控制引擎
     */
    public final MoveWorker Move;

    /**
     * 图像渲染引擎
     */
    public final RenderWorker Render;

    /**
     * 碰撞检测引擎
     */
    public final CollideWorker Collide;

    /**
     * 特殊事件处理引擎
     */
    public final DelayedWorker Delayed;

    /**
     * 主引擎状态
     */
    private boolean running;

    /**
     * 记录暂停时间
     */
    private long gap;

    /**
     * 记录上次引擎暂停时间
     */
    private long last;

    public BaseEngine(int width, int height, int margin) {
        // 物理边界
        Entity physicsBoundary = new Entity(new Rectangle(-margin, -margin, width + margin, height + margin));
        Move = new MoveWorker(this, physicsBoundary);
        Render = new RenderWorker(this, physicsBoundary, width, height);
        Collide = new CollideWorker(this, physicsBoundary);
        Delayed = new DelayedWorker(this);
        running = false;
        last = -1;
    }

    public void resume() {
        Move.resume();
        Render.resume();
        Collide.resume();
        Delayed.resume();
        running = true;
        if (last > 0) {
            gap += System.currentTimeMillis() - last;
        }
    }

    public void pause() {
        last = System.currentTimeMillis();
        Move.pause();
        Render.pause();
        Collide.pause();
        Delayed.pause();
        running = false;
    }

    public void stop() {
        Move.stop();
        Render.stop();
        Collide.stop();
        Delayed.stop();
        running = false;
    }

    public boolean isRunning() {
        return running;
    }

    /**
     * 获取游戏内部时间
     * 
     * @return 游戏内部时间
     */
    public long clock() {
        return SystemClock.uptimeMillis() - gap;
    }
}
